#include "Http.hpp"

void TestSplit()
{
    std::string str = "  hello   world nihao hehe   ";
    std::vector<std::string> strs;
    std::cout << Utils::Split(str, " ", &strs) << std::endl;

    for(auto& s : strs)
    {
        std::cout << "[" << s << "]" << std::endl;
    }
}

void TestReadFile()
{
    std::string fileName = "makefile";
    std::string content;
    std::cout << Utils::ReadFile(fileName, &content) << std::endl;
    std::cout << content << std::endl;
}

void TestWriteFile()
{
    std::string fileName = "file";
    std::string data = "writing ...";
    std::cout << Utils::WriteFile(fileName, data) << std::endl;

    std::string content;
    std::cout << Utils::ReadFile(fileName, &content) << std::endl;
    std::cout << content << std::endl;
}

void TestUrlEncode()
{
    /* 测试字符型到十六进制的输出 */
    // char buffer[3] = { 0 };
    // sprintf(buffer, "%02X", '?');
    // std::cout << buffer << std::endl;

    // std::string str = "C++";
    // std::string str = "C  ++";
    std::string str = "http://192.168.1.1:8080/file";

    std::cout << Utils::UrlEncode(str, true) << std::endl;
}

void TestUrlDecode()
{
    /* 测试CharToInt8() */
    // std::string url = "%2B";
    // int8_t first = Utils::CharToInt8(url[1]);
    // int8_t second = Utils::CharToInt8(url[2]);
    // printf("[%d, %d]\n", first, second);
    // char buffer[2] = { 0 };
    // sprintf(buffer, "%c", first * 16 + second);
    // std::cout << "[" << buffer << "]" << std::endl;

    // std::string str = "http://192.168.1.1:8080/file";
    std::string str = "C++";
    std::string encodeStr = Utils::UrlEncode(str, true);
    std::cout << encodeStr << std::endl;

    std::cout << Utils::UrlDecode(encodeStr) << std::endl;
}

void TestStatusCodeDescrib()
{
    std::cout << Utils::StatusCodeDescrib(200) << std::endl;

    std::cout << Utils::StatusCodeDescrib(400) << std::endl;
    std::cout << Utils::StatusCodeDescrib(404) << std::endl;
    std::cout << Utils::StatusCodeDescrib(500) << std::endl;

    std::cout << Utils::StatusCodeDescrib(301) << std::endl;
}

void TestSufMime()
{
    std::cout << Utils::SufMime("file.7z") << std::endl;
    std::cout << Utils::SufMime("file") << std::endl;
    std::cout << Utils::SufMime("file.txt") << std::endl;
    std::cout << Utils::SufMime("file.c") << std::endl;
    std::cout << Utils::SufMime("fil.e.pdf") << std::endl;
}

void TestIsDirAndIsRegugar()
{
    std::cout << Utils::IsDir(".") << std::endl;
    std::cout << Utils::IsDir("makefile") << std::endl;
    std::cout << Utils::IsRegular("makefile") << std::endl;
    std::cout << Utils::IsRegular(".") << std::endl;
}

void TestValidPath()
{
    std::cout << Utils::ValidPath("/file") << std::endl;// 层0
    std::cout << Utils::ValidPath("/dir1/file") << std::endl;// 层1
    std::cout << Utils::ValidPath("/dir1/../file") << std::endl;// 层0
    std::cout << Utils::ValidPath("/dir1/../../") << std::endl;// 层-1
    std::cout << Utils::ValidPath("/dir1/dir2/../.././") << std::endl;// 层0
    std::cout << Utils::ValidPath("/dir1/dir2/../../../") << std::endl;// 层-1
}

void PutFile(const HttpRequest& req, HttpResponse* resp)
{
    DBG_LOG("PutFile()");
}

void TestRegex()
{
#if 0
    // HTTP请求行格式：GET /path/login?username=zhangsan&password=123456 HTTP/1.1\r\n
    std::string str = "GET /path/login?username=xxx&passwd=xxx HTTP/1.1\r\n";
    std::smatch matches;// 保存结果的容器

    // 
    std::regex rgx("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?");
    /*
        (GET|HEAD|POST|PUT|DELETE)：匹配并提取其中任意一个字符串，直到遇到空格
        ([^?]*)：[^?]匹配非'?'字符，*表示匹配0次或多次，()提取
        \\?(.*) ：\\?表示'?'字符，(.*)表示提取任意字符，即匹配并提取'?'之后的任意字符，直到遇到空格
        (HTTP/1\\.[01])：[01]表示匹配0或1，\\.表示'.'，(HTTP/1\\.[01])表示匹配并提取以'HTTP/1.'开头且以0或1结尾的字符串
        (?:\n|\r\n)?：(?:字符串)表示匹配指定格式字符串但不提取，后面的'?'表示匹配前面的表达式0次或1次
        (?:\\?(.*))?：与上同理
    */
    bool ret = std::regex_match(str, matches, rgx);
    if(ret == false) return;
    for(int i = 0; i < matches.size(); ++i)
    {
        std::cout << i << ": " << matches[i] << std::endl;
    }
#else
    using HandleFunc = std::function<void(const HttpRequest&, HttpResponse*)>;
    using Route_t = std::vector<std::pair<std::regex, HandleFunc>>;
    Route_t putRoute;
    std::smatch matches;// 保存结果的容器
    putRoute.push_back(std::make_pair(std::regex("/upload"), PutFile));
    DBG_LOG("SIZE: %ld", putRoute.size());
    std::string path = "/upload";
    if(std::regex_match(path, matches, putRoute.front().first))
        std::cout << "SUCCESS" << std::endl;
#endif
}

#if 0 // 未包含相关头文件，为避免编译错误，条件编译选择不编译这部分代码
void TestHttpServer()
{
    HttpServer server(9000);
    server.SetRootPath("www");
    server.SetThreadCount(2);
}
#endif

void TestBuffer()
{
    Buffer buf;
    const char* str = "hello world 1";
    buf.Write(str, strlen(str));

    char tmp[20] = { 0 };
    buf.Read(tmp, buf.ReadAbleSize());

    std::cout << tmp << std::endl;

    std::string stri;
    buf.ReadAsString(stri, buf.ReadAbleSize());
    std::cout << stri << std::endl;

    Buffer buffer;
    buffer.WriteBuffer(buf);
    buffer.ReadAndPop(tmp, buffer.ReadAbleSize());
    std::cout << tmp << std::endl;

    buffer.Clear();
    const char* str2 = "hello world1\nhaha";
    buffer.WriteString(str2);
    std::cout << buffer.GetLine() << std::endl;
    buffer.Clear();
    const char* str3 = "hello world2\r\nhaha";
    buffer.WriteString(str3);
    std::cout << buffer.GetLine() << std::endl;
}

void TestSTL()
{
    std::unordered_map<int, int> map;
    map.erase(10);
}

int main()
{
    // TestSplit();
    // TestReadFile();
    // TestWriteFile();
    // TestUrlEncode();
    // TestUrlDecode();
    // TestStatusCodeDescrib();
    // TestSufMime();
    // TestIsDirAndIsRegugar();
    // TestValidPath();
    // TestRegex();
    // TestHttpServer();
    // TestBuffer();
    TestSTL();

    return 0;
}